﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
using System.ComponentModel.Design;
using System.Windows.Forms.Design;

namespace SemenQuest.SubWindows
{
    public partial class SettingSlider : UserControl
    {
        #region Properties
        #region Behavior
        [Category("Setting Values")]
        [DefaultValue(1000)]
        [Description("The maximum value possible")]
        public Int32 Maximum
        {
            get { return Bar.Maximum; }
            set
            {
                if (value != Maximum)
                {
                    if (value < Minimum)
                    {
                        value = Minimum;
                    }
                    this.SuspendLayout();
                    Max_label.Text = value.ToString();
                    Max_label.Location = new Point(PanelSlider.Width - Max_label.Size.Width, Max_label.Location.Y);

                    Bar.Maximum = value;

                    Int32 width = (value.ToString().Length + 1) * 7;
                    if (width < Btn_Default.Width)
                    {
                        width = Btn_Default.Width;
                    }
                    Box.Width = width;

                    if (value < Value)
                    {
                        Value = value;
                        Box.Text = value.ToString();
                    }
                    SetTrackBarValues();
                    this.ResumeLayout(true);
                }
            }
        }

        [Category("Setting Values")]
        [DefaultValue(0)]
        [Description("The minimum value possible")]
        public Int32 Minimum
        {
            get { return Bar.Minimum; }
            set
            {
                if (value != Minimum)
                {
                    if (value > Maximum)
                    {
                        value = Maximum;
                    }
                    this.SuspendLayout();
                    Min_label.Text = value.ToString();

                    Bar.Minimum = value;
                    Bar.TickFrequency = (Maximum - value) / 20;
                    Bar.LargeChange = Bar.TickFrequency;
                    Bar.SmallChange = (Maximum - value) / 100;
                    if (value > Value)
                    {
                        Value = value;
                        Box.Text = value.ToString();
                    }
                    SetTrackBarValues();
                    this.ResumeLayout(true);
                }
            }
        }

        [Category("Setting Values")]
        [Description("The current value")]
        public Int32 Value
        {
            get { return _Value; }
            set
            {
                if (value != _Value)
                {
                    if (value >= Maximum)
                    {
                        value = Maximum;
                    }
                    else if (value <= Minimum)
                    {
                        value = Minimum;
                    }
                    _Value = value;

                    PrivateValueChangedHandler handler = PrivateValueChanged;
                    if (handler != null)
                        handler("Value", value);
                    ValueChangedHandler handler2 = ValueChanged;
                    if (handler2 != null)
                        handler2(this, value);
                }
            }
        }
        private Int32 _Value;

        [Category("Setting Values")]
        [DefaultValue(500)]
        [Description("The default value")]
        public Int32 DefaultValue
        {
            get
            {
                return _DefaultValue;
            }
            set
            {
                if (value != _DefaultValue)
                {
                    if (value > Maximum)
                    {
                        value = Maximum;
                    }
                    else if (value < Minimum)
                    {
                        value = Minimum;
                    }
                    _DefaultValue = value;
                    var handler = PrivateValueChanged;
                    if (handler != null)
                        handler("DefaultValue", value);
                }
            }
        }
        private Int32 _DefaultValue = 500;
        #endregion
        #region Appearance
        [Category("Title label")]
        [DefaultValue("Title")]
        [Description("Title label")]
        public String Title
        {
            get { return Title_label.Text; }
            set
            {
                if (value != Title_label.Text)
                {
                    Title_label.Text = value;
                    if (ShowTitle)
                    {
                        Table.MinimumSize = new System.Drawing.Size(Title_label.Width + 7, 0);
                    }
                    else
                    {
                        Table.MinimumSize = new System.Drawing.Size(160, 0);
                    }
                }
            }
        }
        [Category("Title label")]
        [DefaultValue(true)]
        [Description("Enable/Disable the Title label")]
        public Boolean ShowTitle
        {
            get { return _ShowTitle; }
            set
            {
                if (value != Title_label.Visible)
                {
                    _ShowTitle = value;
                    Title_label.Visible = value;
                    if (value)
                    {
                        Table.MinimumSize = new System.Drawing.Size(Title_label.Width + 7, 0);
                    }
                    else
                    {
                        Table.MinimumSize = new System.Drawing.Size(160, 0);
                    }
                    Invalidate();
                }
            }
        }
        private Boolean _ShowTitle = true;
        [Category("Title label")]
        [DefaultValue(typeof(Font), "Microsoft Sans Serif, 9pt, style=Bold")]
        [Description("The Font used to display the Title")]
        public Font TitleFont
        {
            get { return Title_label.Font; }
            set
            {
                if (value != Title_label.Font)
                {
                    Title_label.Font = value;
                }
            }
        }
        [Category("Title label")]
        [DefaultValue(typeof(Color), "ControlText")]
        [Description("The color of the Title")]
        public Color TitleColor
        {
            get { return Title_label.ForeColor; }
            set
            {
                if (value != Title_label.ForeColor)
                {
                    Title_label.ForeColor = value;
                }
            }
        }



        [Category("Min/Max labels")]
        [DefaultValue(true)]
        [Description("Show/Hide the minimum and maximum labels")]
        public Boolean ShowMinMaxValues
        {
            get { return _ShowMinMaxValues; }
            set
            {
                if (value != Min_label.Visible)
                {
                    _ShowMinMaxValues = value;
                    Min_label.Visible = value;
                    Max_label.Visible = value;
                }
            }
        }
        private Boolean _ShowMinMaxValues = true;
        [Category("Min/Max labels")]
        [DefaultValue(typeof(Font), "Microsoft Sans Serif, 7.8pt, style=Regular")]
        [Description("The Font used to display the Min/Max values")]
        public Font MinMaxFont
        {
            get { return Min_label.Font; }
            set
            {
                if (value != Min_label.Font)
                {
                    Min_label.Font = value;
                    Max_label.Font = value;
                }
            }
        }
        [Category("Min/Max labels")]
        [DefaultValue(typeof(Color), "ControlDarkDark")]
        [Description("The color of the Min/Max values")]
        public Color MinMaxColor
        {
            get { return Min_label.ForeColor; }
            set
            {
                if (value != Min_label.ForeColor)
                {
                    Min_label.ForeColor = value;
                    Max_label.ForeColor = value;
                }
            }
        }



        [Category("Default Button")]
        [DefaultValue(true)]
        [Description("Show/Hide the default button")]
        public Boolean ShowDefaultButton
        {
            get { return _ShowDefaultButton; }
            set
            {
                _ShowDefaultButton = value;
                Btn_Default.Visible = value;
            }
        }
        private Boolean _ShowDefaultButton = true;



        [Category("Title Underline")]
        [DefaultValue(typeof(Color), "Highlight")]
        [Description("Color applied to the title underline")]
        public Color UnderlineColor
        {
            get
            {
                return _UnderlineColor;
            }
            set
            {
                _UnderlineColor = value;
                PanelLine.Invalidate();
            }
        }
        private Color _UnderlineColor = SystemColors.Highlight;
        [Category("Title Underline")]
        [DefaultValue(true)]
        [Description("Title underline enabled")]
        public Boolean ShowUnderline
        {
            get
            {
                return _ShowUnderline;
            }
            set
            {
                if (value != PanelLine.Visible)
                {
                    _ShowUnderline = value;
                    PanelLine.Visible = value;
                }
            }
        }
        private Boolean _ShowUnderline = true;
        [Category("Title Underline")]
        [DefaultValue(80)]
        [Description("Title underline % of the component width")]
        public Int32 UnderlineLength
        {
            get
            {
                return _UnderlineLength;
            }
            set
            {
                if (value > 100 || value < 0)
                    throw new System.ArgumentOutOfRangeException("UnderlineLength", "Parameter must be an integer between 0 and 100");
                _UnderlineLength = value;
                PanelLine.Invalidate();
            }
        }
        private Int32 _UnderlineLength = 80;




        [Category("Track Bar")]
        [DefaultValue(true)]
        [Description("Colorize the TrackBar Channel on left side of Slider")]
        public Boolean TrackBarChannelColorize
        {
            get { return _TrackBarChannelColorize; }
            set
            {
                _TrackBarChannelColorize = value;
                barLine.Visible = value;
            }
        }
        private Boolean _TrackBarChannelColorize = true;
        [Category("Track Bar")]
        [DefaultValue(typeof(TrackBarColorizationTypes), "OneColor")]
        [Description("Colorization type of the TrackBar Channel Colorazation")]
        public TrackBarColorizationTypes TrackBarChannelColorizationType
        {
            get { return barLine.ColorazationType; }
            set
            {
                barLine.ColorazationType = value;
            }
        }
        public enum TrackBarColorizationTypes
        {
            OneColor,
            GradientLeftToRight,
            GradientRightToLeft,
        }
        [Category("Track Bar")]
        [DefaultValue(typeof(Color), "Highlight")]
        [Description("Start Color used for the TrackBar Channel Colorazation")]
        public Color TrackBarChannelFirstColor
        {
            get { return barLine.FirstColor; }
            set
            {
                barLine.FirstColor = value;
            }
        }
        [Category("Track Bar")]
        [DefaultValue(typeof(Color), "231, 234, 234")]
        [Description("Second Color of the TrackBar Channel Colorazation")]
        public Color TrackBarChannelSecondColor
        {
            get { return barLine.SecondColor; }
            set
            {
                barLine.SecondColor = value;
            }
        }
        private BarLine barLine { get; set; }
        [Category("Track Bar")]
        [DefaultValue(true)]
        [Description("Adjust the trackbars steps, deactivate to use manual steps")]
        public Boolean TrackBarAutomaticStepSize
        {
            get { return _TrackBarAutomaticStepSize; }
            set
            {
                _TrackBarAutomaticStepSize = value;
                if (!value)
                {
                    Bar.SmallChange = _TrackBarSmallSteps;
                    Bar.LargeChange = _TrackBarLargeSteps;
                    Bar.TickFrequency = _TrackBarLargeSteps;
                    Invalidate();
                }
                else
                {
                    SetTrackBarValues();
                    Invalidate();
                }
            }
        }
        private Boolean _TrackBarAutomaticStepSize = true;
        [Category("Track Bar")]
        [DefaultValue(1)]
        [Description("Second Color of the TrackBar Channel Colorazation")]
        public Int32 TrackBarSmallSteps
        {
            get { return _TrackBarSmallSteps; }
            set
            {
                _TrackBarSmallSteps = value;
                if (!_TrackBarAutomaticStepSize)
                {
                    Bar.SmallChange = value;
                }
            }
        }
        private Int32 _TrackBarSmallSteps = 1;
        [Category("Track Bar")]
        [DefaultValue(10)]
        [Description("Second Color of the TrackBar Channel Colorazation")]
        public Int32 TrackBarLargeSteps
        {
            get { return _TrackBarLargeSteps; }
            set
            {
                _TrackBarLargeSteps = value;
                if (!_TrackBarAutomaticStepSize)
                {
                    Bar.LargeChange = value;
                    Bar.TickFrequency = value;
                }
            }
        }
        private Int32 _TrackBarLargeSteps = 10;


        #endregion
        #region Layout
        [DefaultValue(true)]
        public override bool AutoSize
        {
            get { return base.AutoSize; }
            set { base.AutoSize = value; }
        }
        [DefaultValue(typeof(AutoSizeMode), "GrowAndShrink")]
        public new AutoSizeMode AutoSizeMode
        {
            get { return base.AutoSizeMode; }
            set { base.AutoSizeMode = value; }
        }
        #endregion
        #region Hidden Properties

        [Browsable(false)]
        public override bool AllowDrop
        { get { return base.AllowDrop; } set { base.AllowDrop = value; } }
        [Browsable(false)]
        public override bool AutoScroll
        { get { return base.AutoScroll; } set { base.AutoScroll = value; } }
        [Browsable(false)]
        public override Point AutoScrollOffset
        { get { return base.AutoScrollOffset; } set { base.AutoScrollOffset = value; } }
        [Browsable(false)]
        public override Image BackgroundImage
        { get { return base.BackgroundImage; } set { base.BackgroundImage = value; } }
        [Browsable(false)]
        public override ImageLayout BackgroundImageLayout
        { get { return base.BackgroundImageLayout; } set { base.BackgroundImageLayout = value; } }
        [Browsable(false)]
        public override System.Drawing.Color ForeColor
        { get { return base.ForeColor; } set { base.ForeColor = value; } }
        [Browsable(false)]
        public override Font Font
        { get { return base.Font; } set { base.Font = value; } }
        [Browsable(false)]
        public new Padding Padding
        { get { return base.Padding; } set { base.Padding = value; } }
        [Browsable(false)]
        public new Size AutoScrollMargin
        { get { return base.AutoScrollMargin; } set { base.AutoScrollMargin = value; } }
        [Browsable(false)]
        public new Size AutoScrollMinSize
        { get { return base.AutoScrollMinSize; } set { base.AutoScrollMinSize = value; } }
        [Browsable(false)]
        public new Boolean UseWaitCursor
        { get { return base.UseWaitCursor; } set { base.UseWaitCursor = value; } }
        [Browsable(false)]
        public override RightToLeft RightToLeft
        { get { return base.RightToLeft; } set { base.RightToLeft = value; } }
        [Browsable(false)]
        public override Cursor Cursor
        { get { return base.Cursor; } set { base.Cursor = value; } }
        #endregion
        #endregion

        #region Events & Delegates
        public delegate void ValueChangedHandler(Control sender, Int32 Value);
        public event ValueChangedHandler ValueChanged;
        private delegate void PrivateValueChangedHandler(String str, Int32 Value);
        private event PrivateValueChangedHandler PrivateValueChanged;
        #endregion

        #region Classes
        private class BarLine : Control
        {
            public BarLine(TrackBar parent)
                : base(parent, String.Empty)
            {
                this.ResizeRedraw = true;
                this.BackColor = Color.FromArgb(255, 231, 234, 234);
                this.Parent.Resize += Bar_Resize;
                Bar_Resize(this.Parent, EventArgs.Empty);
                parent.ValueChanged += Bar_ValueChanged;
            }

            //public Int32 Moved { get { return _Moved; } set { _Moved = value; Invalidate(); } }
            //private Int32 _Moved;
            public Color FirstColor
            {
                get { return _FirstColor; }
                set
                {
                    _FirstColor = value;
                    Invalidate();
                }
            }
            private Color _FirstColor = SystemColors.Highlight;
            public Color SecondColor
            {
                get { return _SecondColor; }
                set
                {
                    _SecondColor = value;
                    Invalidate();
                }
            }
            private Color _SecondColor = Color.FromArgb(255, 231, 234, 234);
            public TrackBarColorizationTypes ColorazationType
            {
                get { return _ColorazationType; }
                set
                {
                    _ColorazationType = value;
                    Invalidate();
                }
            }
            private TrackBarColorizationTypes _ColorazationType;

            private void Bar_Resize(Object sender, EventArgs e)
            {
                Rectangle ChannelInfo = Channel;
                this.Location = new Point(ChannelInfo.X + 1, ChannelInfo.Y + 1);
                this.Height = ChannelInfo.Height - 2;
                this.Width = Slider.X - ChannelInfo.X;
            }
            private void Bar_ValueChanged(Object sender, EventArgs e)
            {
                this.Width = Slider.X - Channel.X;
            }
            protected override void OnPaint(PaintEventArgs e)
            {
                base.OnPaint(e);
                Rectangle slider = Slider;
                Color color1, color2;
                switch (ColorazationType)
                {
                    case TrackBarColorizationTypes.OneColor:
                        color1 = FirstColor;
                        color2 = FirstColor;
                        break;
                    case TrackBarColorizationTypes.GradientLeftToRight:
                        color1 = FirstColor;
                        color2 = SecondColor;
                        break;
                    case TrackBarColorizationTypes.GradientRightToLeft:
                        color1 = SecondColor;
                        color2 = FirstColor;
                        break;
                    default:
                        throw new InvalidEnumArgumentException("TrackBar Channel Colorazation type not regonized");
                }
                try
                {
                    using (Brush gradientBrush = new LinearGradientBrush(Point.Empty, new Point(slider.X - this.Location.X + 1, 0), color1, color2))
                    using (Pen gradientPen = new Pen(gradientBrush, this.Height + 2))
                    {
                        e.Graphics.DrawLine(gradientPen, 0, 0, slider.X - this.Location.X + 1, 0);
                    }
                }
                catch { }
            }

            #region TrackBar slider og channel placering
            [DllImport("user32.dll", EntryPoint = "SendMessageW")]
            private extern static IntPtr SendMessageRect(IntPtr hWnd, Int32 msg, IntPtr wp, ref RECT lp);

            private struct RECT { public Int32 left, top, right, bottom;}
            private const Int32 TBM_GETCHANNELRECT = 0x400 + 26;
            private const Int32 TBM_GETTHUMBRECT = 0x400 + 25;

            private Rectangle Slider
            {
                get
                {
                    RECT rc = new RECT();
                    SendMessageRect(Parent.Handle, TBM_GETTHUMBRECT, IntPtr.Zero, ref rc);
                    return new Rectangle(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
                }
            }
            private Rectangle Channel
            {
                get
                {
                    RECT rc = new RECT();
                    SendMessageRect(Parent.Handle, TBM_GETCHANNELRECT, IntPtr.Zero, ref rc);
                    return new Rectangle(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
                }
            }
            #endregion


        }
        #endregion

        #region Constructor
        public SettingSlider()
        {
            InitializeComponent();
            PanelLine.Paint += PanelLine_Paint; //Paint the Line below the Title
            CountTimer.Tag = new KeyArgs(); //Used to Count the Value with the Ctrl key and arrow keys

            barLine = new BarLine(Bar);

            Box.Width = (Maximum.ToString().Length + 1) * 7;

            #region Set en minimum størrelse på Control for at der ikke sker grafik fejl ved resize
            if (ShowTitle)
            {
                Table.MinimumSize = new System.Drawing.Size(Title_label.Width + 7, 0);
                if (Table.MinimumSize.Width < 160)
                {
                    Table.MinimumSize = new System.Drawing.Size(160, 0);
                }
            }
            else
            {
                Table.MinimumSize = new System.Drawing.Size(160, 0);
            }
            #endregion

            //Denne event subscription sørger for at der ikke dukker en focus cue op rundt om trackbaren
            Bar.GotFocus += delegate(Object sender, EventArgs e)
            {
                SendMessage(this.Handle, 0x0128, MakeParam(0x1, 0x1), 0x0);
            };

            #region Data Binding af Value mellem Controls
            //Bar.ValueChanged += delegate(Object sender, EventArgs e)
            //{
            //    Value = Bar.Value;
            //};

            //Box.TextChanged += delegate(Object sender, EventArgs e)
            //{
            //    Value = Convert.ToInt32(Box.Text);
            //};

            //Link Bar og Box sammen (Two Way)
            Box.DataBindings.Add("Text", Bar, "Value", false, DataSourceUpdateMode.OnPropertyChanged, "0");
            //Link Bar til Value (One Way)
            Bar.DataBindings.Add("Value", this, "Value", false, DataSourceUpdateMode.OnPropertyChanged, 0);
            //Link Value til Bar (One Way)
            PrivateValueChanged += delegate(String str, Int32 value)
            {
                if (str == "Value")
                {
                    Bar.Value = Value;
                    Box.Text = Value.ToString();
                    Btn_Default.Enabled = Value != DefaultValue;
                }
                if (str == "DefaultValue")
                {
                    Btn_Default.Enabled = Value != DefaultValue;
                }
            };
            #endregion
        }
        #endregion

        #region Send Windows Messages
        //Remove focus cue message
        [DllImport("user32.dll")]
        private extern static Int32 SendMessage(IntPtr hWnd, UInt32 msg, Int32 wParam, Int32 lParam);
        private static Int32 MakeParam(Int32 loWord, Int32 hiWord)
        {
            return (hiWord << 16) | (loWord & 0xffff);
        }
        #endregion

        #region Paint Underline
        private void PanelLine_Paint(Object sender, PaintEventArgs e)
        {
            if (ShowUnderline)
            {
                using (Brush gradientBrush = new LinearGradientBrush(Point.Empty, new Point(this.Size.Width * UnderlineLength / 100, 0), UnderlineColor, this.BackColor))
                using (Pen aGradientPen = new Pen(gradientBrush, 3))
                {
                    e.Graphics.DrawLine(aGradientPen, new Point(7, 0), new Point(this.Size.Width * UnderlineLength / 100 - 1, 0));
                }
            }
        }
        #endregion

        /// <summary>
        /// Denne funktion bruges til at beregne det optimale frekvens for ticks på slideren
        /// </summary>
        private void SetTrackBarValues()
        {
            if (!_TrackBarAutomaticStepSize)
                return;
            Int32 optimalTicks = Bar.Width / 20;
            Int32 StartValue = optimalTicks - 10;
            Int32 EndValue = optimalTicks + 10;
            if (StartValue <= 0)
            {
                StartValue = 1;
                EndValue = optimalTicks * 2 + 1;
            }

            List<Int32[]> ValidFreqs = new List<Int32[]>();
            for (Int32 x = StartValue; x <= EndValue; x++)
            {
                Double freq = (Double)Maximum / (Double)x;
                Int32 ValidFreq = Convert.ToInt32(freq);
                if (ValidFreq == freq)
                {
                    ValidFreqs.Add(new Int32[2] { x, ValidFreq });
                }
            }
            if (ValidFreqs.Count == 0)
            {
                Bar.TickFrequency = Maximum / optimalTicks;
                return;
            }
            else if (ValidFreqs.Count == 1)
            {
                Bar.TickFrequency = ValidFreqs[0][1];
                return;
            }

            Int32[] Nearest = ValidFreqs[0];
            for (Int32 x = 1; x < ValidFreqs.Count; x++)
            {
                Int32[] tmp = ValidFreqs[x];
                if (Math.Abs(optimalTicks - tmp[0]) <= Math.Abs(optimalTicks - Nearest[0]))
                {
                    Nearest = tmp;
                    continue;
                }
                break;
            }
            Bar.TickFrequency = Nearest[1];
            Bar.LargeChange = Bar.TickFrequency;
            Int32 SmallChange = Bar.LargeChange / 10;
            if (SmallChange < 1)
            {
                SmallChange = 1;
            }
            Bar.SmallChange = SmallChange;
        }

        /// <summary>
        /// Reset settings to defaults
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Btn_Default_Click(Object sender, EventArgs e)
        {
            Value = DefaultValue;
            Btn_Default.Enabled = false;
        }

        private void Box_KeyPress(Object sender, KeyPressEventArgs e)
        {
            //1. if not digit or control, return
            if (!Char.IsDigit(e.KeyChar) && !Char.IsControl(e.KeyChar))
            {
                e.Handled = true;
                return;
            }

            //2. if digit, number to large?
            if (Char.IsDigit(e.KeyChar))
            {
                //Get number as string
                String StringValue = Box.Text;
                if (Box.SelectionLength > 0)
                {
                    StringValue = StringValue.Remove(Box.SelectionStart, Box.SelectionLength);
                }
                StringValue = StringValue.Insert(Box.SelectionStart, e.KeyChar.ToString());

                //Try Parse
                Int32 i;
                if (!Int32.TryParse(StringValue, out i))
                {
                    e.Handled = true;
                    return;
                }

                if (i > Maximum)
                {
                    e.Handled = true;
                    Box.Text = Maximum.ToString();
                }
            }
        }
        private void SettingSlider_Resize(Object sender, EventArgs e)
        {
            SetTrackBarValues();
        }

        #region Value change via arrows
        private class KeyArgs
        {
            public Boolean CtrlPressed { get; set; }
            public Boolean UpPressed { get; set; }
            public Boolean DownPressed { get; set; }
            public Boolean UpOrDownPressed { get { return UpPressed || DownPressed; } }
            public Boolean UpAndDownPressed { get { return UpPressed && DownPressed; } }
        }
        private void Box_KeyDown(Object sender, KeyEventArgs e)
        {
            if (e.Control)
            {
                e.Handled = true;
                (CountTimer.Tag as KeyArgs).CtrlPressed = true;
            }
            if (e.KeyCode == Keys.Down)
            {
                e.Handled = true;
                (CountTimer.Tag as KeyArgs).DownPressed = true;
            }
            if (e.KeyCode == Keys.Up)
            {
                e.Handled = true;
                (CountTimer.Tag as KeyArgs).UpPressed = true;
            }

            if ((CountTimer.Tag as KeyArgs).UpOrDownPressed && !CountTimer.Enabled)
            {
                CountTimer.Interval = 500;
                Count((CountTimer.Tag as KeyArgs));
                CountTimer.Start();
            }
        }
        private void Box_KeyUp(Object sender, KeyEventArgs e)
        {
            if (!e.Control) //if nessesary, so property is not false, if other button is released
            {
                e.Handled = true;
                (CountTimer.Tag as KeyArgs).CtrlPressed = false;
            }
            if (e.KeyCode == Keys.Down)
            {
                e.Handled = true;
                (CountTimer.Tag as KeyArgs).DownPressed = false;
            }
            if (e.KeyCode == Keys.Up)
            {
                e.Handled = true;
                (CountTimer.Tag as KeyArgs).UpPressed = false;
            }


            if (!(CountTimer.Tag as KeyArgs).UpOrDownPressed)
            {
                CountTimer.Stop();
            }
        }
        private void CountTimer_Tick(Object sender, EventArgs e)
        {
            if ((CountTimer.Tag as KeyArgs).UpAndDownPressed)
            {
                return;
            }

            if (CountTimer.Interval != 100)
            {
                CountTimer.Interval = 25;
            }

            /* //Code used to slow down count when close to the edges of limit
            if ((CountTimer.Tag as KeyArgs).UpPressed)
            {
                if (Value > Maximum - Maximum / 10)
                {
                    if (Value > Maximum - Maximum / 20)
                    {
                        if (Value > Maximum - Maximum / 40)
                        {
                            CountTimer.Interval = 400;
                        }
                        else
                        {
                            CountTimer.Interval = 300;
                        }
                    }
                    else
                    {
                        CountTimer.Interval = 200;
                    }
                }
                else
                {
                    CountTimer.Interval = 100;
                }
            }
            else if ((CountTimer.Tag as KeyArgs).DownPressed)
            {
                if (Value < Minimum + Maximum / 10)
                {
                    if (Value < Minimum + Maximum / 20)
                    {
                        if (Value < Minimum + Maximum / 40)
                        {
                            CountTimer.Interval = 400;
                        }
                        else
                        {
                            CountTimer.Interval = 300;
                        }
                    }
                    else
                    {
                        CountTimer.Interval = 200;
                    }
                }
                else
                {
                    CountTimer.Interval = 100;
                }
            }
            */
            Count(CountTimer.Tag as KeyArgs);
        }
        private void Count(KeyArgs e)
        {
            if (e.UpPressed && Value < Maximum)
            {
                if (e.CtrlPressed && Value < (Maximum - 10))
                {
                    Value += Bar.LargeChange;
                }
                else
                {
                    Value += Bar.SmallChange;
                }
            }
            else if (e.DownPressed && Value > Minimum)
            {
                if (e.CtrlPressed && Value > Minimum + 10)
                {
                    Value -= Bar.LargeChange;
                }
                else
                {
                    Value -= Bar.SmallChange;
                }
            }
        }
        #endregion

    }
}
